Passed
Push — develop ( 109efd...60ff03 )
by Andrew
07:24
created

webpack.prod.js ➔ extract   A

Complexity

Conditions 1
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 2
nop 1
1
// webpack.prod.js - production builds
2
3
const LEGACY_CONFIG = 'legacy';
4
const MODERN_CONFIG = 'modern';
5
6
// node modules
7
const webpack = require('webpack');
8
const glob = require("glob-all");
9
const path = require('path');
10
const git = require('git-rev-sync');
11
const moment = require('moment');
12
// webpack plugins
13
const merge = require('webpack-merge');
14
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
15
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
16
const PurgecssPlugin = require("purgecss-webpack-plugin");
17
const whitelister = require('purgecss-whitelister')
18
// config files
19
const pkg = require('./package.json');
20
const common = require('./webpack.common.js');
21
22
// Custom PurgeCSS extractor for Tailwind that allows special characters in
23
// class names.
24
//
25
// https://github.com/FullHuman/purgecss#extractor
26
class TailwindExtractor {
27
    static extract(content) {
28
        return content.match(/[A-Za-z0-9-_:\/]+/g) || [];
29
    }
30
}
31
32
// File banner banner
33
const configureBanner = () => {
34
    return {
35
        banner: [
36
            '/*!',
37
            ' * @project        ' + pkg.copyright,
38
            ' * @name           ' + '[filebase]',
39
            ' * @author         ' + pkg.author,
40
            ' * @build          ' + moment().format('llll') + ' ET',
41
            ' * @release        ' + git.long() + ' [' + git.branch() + ']',
42
            ' * @copyright      Copyright (c) ' + moment().format('YYYY') + ' ' + pkg.copyright,
43
            ' *',
44
            ' */',
45
            ''
46
        ].join('\n'),
47
        raw: true
48
    };
49
};
50
51
// Configure PurgeCSS
52
const configurePurgeCss = () => {
53
    let paths = [];
54
    // Configure whitelist paths
55
    for (const [key, value] of Object.entries(pkg.purgeCss.paths)) {
0 ignored issues
show
Unused Code introduced by
The variable key seems to be never used. Consider removing it.
Loading history...
56
        paths.push(path.join(__dirname, value));
57
    }
58
59
    return {
60
        paths: glob.sync(paths),
61
        whitelist: whitelister(pkg.purgeCss.whitelist),
62
        whitelistPatterns: pkg.purgeCss.whitelistPatterns,
63
        extractors: [{
64
            extractor: TailwindExtractor,
65
            extensions: pkg.purgeCss.extensions
66
        }]
67
    };
68
};
69
70
// Configure optimization
71
const configureOptimization = (buildType) => {
72
    if (buildType === LEGACY_CONFIG) {
73
        return {
74
            minimizer: [
75
                new UglifyJsPlugin({
76
                    cache: true,
77
                    parallel: true,
78
                    sourceMap: true
79
                }),
80
                new OptimizeCSSAssetsPlugin({
81
                    cssProcessorOptions: {
82
                        map: {
83
                            inline: false,
84
                            annotation: true,
85
                        },
86
                        safe: true,
87
                        discardComments: true
88
                    },
89
                })
90
            ]
91
        };
92
    }
93
    if (buildType === MODERN_CONFIG) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if buildType === MODERN_CONFIG is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
94
        return {
95
            minimizer: [
96
                new UglifyJsPlugin({
97
                    cache: true,
98
                    parallel: true,
99
                    sourceMap: true
100
                }),
101
            ]
102
        };
103
    }
104
};
105
106
// Production module exports
107
module.exports = [
108
    merge(
109
        common.legacyConfig,
110
        {
111
            mode: 'production',
112
            devtool: 'source-map',
113
            optimization: configureOptimization(LEGACY_CONFIG),
114
            plugins: [
115
                new PurgecssPlugin(
116
                    configurePurgeCss()
117
                ),
118
                new webpack.BannerPlugin(
119
                    configureBanner()
120
                ),
121
            ]
122
        }
123
    ),
124
    merge(
125
        common.modernConfig,
126
        {
127
            mode: 'production',
128
            devtool: 'source-map',
129
            optimization: configureOptimization(MODERN_CONFIG),
130
            plugins: [
131
                new webpack.BannerPlugin(
132
                    configureBanner()
133
                ),
134
            ]
135
        }
136
    ),
137
];
138